package many.to.one.both;

import org.hibernate.Session;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import utils.HibernateUtils;

public class HibernateTest {
	
	private Session session;

	@Before
	public void before() {
		session = HibernateUtils.getSession();
		session.beginTransaction();
	}
	
	@Test
	public void testDelete(){
		//在不设定级联关系的情况下, 且 1 这一端的对象有 n 的对象在引用, 
		//不能直接删除 1 这一端的对象
		Customer customer = (Customer) session.get(Customer.class, 1);
		session.delete(customer); 
	}
	
	@Test
	public void testUpdat2(){
		Customer customer = (Customer) session.get(Customer.class, 1);
		//当前的属性值进行更改
		customer.getOrders().iterator().next().setOrderName("GGG"); 
	}
	
	
	//这里没有使用fetch=join级联查询，会进行两次slelect查询
	@Test
	public void testUpdate(){
		Order order = (Order) session.get(Order.class, 1);
		order.getCustomer().setCustomerName("AAA");
	}
	
	@Test
	public void testMany2OneGet() {
		/**
		 * 1.在查询多对一的一端时候，默认情况(fetch=select)只查询多对一的一端
		 * 2.如果这里是fetch=join 的话那么一次将会查询所有数据
		 */
		Order order = (Order) session.get(Order.class, 1);
		System.out.println(order.getOrderName()); 
		
		System.out.println(order.getCustomer().getClass().getName());
		
		//2. 在需要使用到关联的对象时, 才发送对应的 SQL(fetch=select) 语句.
		System.out.println(order.getCustomer().getCustomerName());
		
		//session.close();
		/**
		 * 1.在查询 Customer 对象时, 由多的一端导航到 1 的一端时, 
		 * 2.若此时 session 已被关闭, 则默认情况下
		 * 3.会发生 LazyInitializationException 异常
		 * 5. 获取 Order 对象时, 默认情况下, 其关联的 Customer 对象是一个代理对象!
		 */
		Customer customer = order.getCustomer();
		System.out.println(customer.getCustomerName());
		
	}
	
	
	@Test
	public void testManyToOne() {
		
		Customer customer = new Customer();
		
		customer.setCustomerName("CC");
		
		Order order = new Order();
		Order order2 = new Order();
		
		order.setOrderName("spring4 book");
		order2.setOrderName("struts2 book");
		
		//维护关系
		order.setCustomer(customer);
		order2.setCustomer(customer);
		
		/**
		 * 1.执行save 先存储customer 后order 3条Insert 2条update
		 * 2.因为 1 的一端和 n 的一端都维护关联关系（双方都维护关系）. 所以会多出 UPDATE
		 * 3.可以在 1 的一端的 set 节点指定 inverse=true, 来使 1 的一端放弃维护关联关系!
		 * 这里就与原来的单向多对一 一样 单一端维护关系 好处是不会多出 UPDATE 语句
		 */
		session.save(customer);
		
		session.save(order);
		session.save(order2);
		
		customer.getOrders().add(order);
		customer.getOrders().add(order2);
		
		
		/**
		 * 先插入 Order, 再插入 Cusomer, 3 条 INSERT, 4 条 UPDATE
		 */
		/*session.save(order);
		session.save(order2);
		
		session.save(customer);
		customer.getOrders().add(order);
		customer.getOrders().add(order2);*/
		
		
	}
	
	@After
	public void after() {
		session.getTransaction().commit();
		session.close();
	}

}
